package com.nulldev.util.crypto.api3.encryptors;

import java.math.BigInteger;
import java.nio.charset.Charset;

import com.nulldev.util.crypto.api2.Cryptable;
import com.nulldev.util.crypto.encryptAPI.litestring.LiteString;
import com.nulldev.util.java.JVMUtil;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.math.MathUtil;
import com.nulldev.util.other.ArrayUtils;
import com.nulldev.util.other.ByteUtils;
import com.nulldev.util.string.StringsUtil;

@Deprecated
public class P2PEC extends Cryptable {

	public P2PEC() {
		super("p2pE.compress");
	}

	@Override
	public String encrypt(String object, String pass) {
		//LoggerFactory.getLogger().error("P2PEC is marked for removal.");
		final BigInteger[] split = MathUtil.getValsB(object);
		final Integer[] pword = MathUtil.getVals(pass);
		for (int i = 0; i < split.length; i++) {
			final BigInteger val = split[i];
			BigInteger newVal = val;
			for (final int p : pword) {
				newVal = newVal.multiply(new BigInteger(String.valueOf(p)));
			}
			split[i] = newVal;
		}
		return ByteUtils.toBase64(LiteString.z2(ArrayUtils.toSList(split)));
	}

	@Override
	public String encrypt(String object, String pass, Charset charset) {
		return this.encrypt(object, pass);
	}

	@Override
	public String decrypt(String object, String pass) {
		//LoggerFactory.getLogger().error("P2PEC is marked for removal.");
		object = LiteString.unzip(ByteUtils.fromBase64(object));
		final BigInteger[] split = MathUtil.getValsBi(object);
		final Integer[] pword = MathUtil.getVals(pass);
		//ArrayUtils.println(pword);
		for (int i = 0; i < split.length; i++) {
			final BigInteger val = split[i];
			BigInteger newVal = val;
			for (final int p : pword) {
				try {
					newVal = newVal.divide(new BigInteger(String.valueOf(p)));
				}catch (ArithmeticException e) {
					log.error("Expected decrypt failure. Reason: " + e.getMessage() + " | p = " + p + ", newVal = " + newVal.toString());
				}
			}
			split[i] = newVal;
		}
		return StringsUtil.toStandard(split);
	}

	@Override
	public String decrypt(String object, String pass, Charset charset) {
		return this.decrypt(object, pass);
	}

	@Override
	public String toPGPString(final String in) {
		final StringBuilder b = new StringBuilder();
		b.append("--START P2P BLOCK---").
			append(JVMUtil.lineSep()).
			append("Type: EC").
			append(JVMUtil.lineSep()).
			append("Iterations: 1").
			append(JVMUtil.lineSep()).
			append("Data: {" + in + "}").
			append(JVMUtil.lineSep()).
			append("----END P2P BLOCK---");
		return b.toString();
	}
	
	@Override
	public String toPGPString(final String in, final String key) {
		final StringBuilder b = new StringBuilder();
		b.append("--START P2P BLOCK---").
			append(JVMUtil.lineSep()).
			append("Type: EC").
			append(JVMUtil.lineSep()).
			append("Iterations: 1").
			append(JVMUtil.lineSep()).
			append("Key: " + key).
			append(JVMUtil.lineSep()).
			append("Data: {" + in + "}").
			append(JVMUtil.lineSep()).
			append("----END P2P BLOCK---");
		return b.toString();
	}
}
